package cn.dansj.common.utils.spring.request;

import cn.dansj.common.processor.meta.WriteToAutoConfiguration;
import cn.dansj.common.utils.json.JSONUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.core.Ordered;

import javax.servlet.*;
import java.io.IOException;

@EnableConfigurationProperties(HttpRequestProperties.class)
@WriteToAutoConfiguration
public class HttpServletRequestConfiguration implements Filter, Ordered, WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
    private static final Logger logger = LoggerFactory.getLogger(HttpServletRequestConfiguration.class);

    private final boolean cors;
    private final String specialCharacters;

    private HttpServletRequestConfiguration(HttpRequestProperties httpRequestProperties) {
        cors = httpRequestProperties.isAllowCors();
        specialCharacters = httpRequestProperties.getSpecialCharacters();
        logger.info("httpRequestProperties(spring.servlet.request): {}", JSONUtils.toJSON(httpRequestProperties));
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        RequestUtils.clearResponseMessage();
        servletRequest = RequestUtils.setRequestAttributesRefreshServletRequest(servletRequest, servletResponse);
        if (cors && RequestUtils.allowCorsCrossOptions()) return;
        filterChain.doFilter(servletRequest, servletResponse);
        RequestUtils.resetRequestAttributes();
        RequestUtils.clearResponseMessage();
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }

    /**
     * 解决 The valid characters are defined in RFC 7230 and RFC 3986 的报错
     */
    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        factory.addConnectorCustomizers(connector -> {
            connector.setProperty("relaxedPathChars", specialCharacters);
            connector.setProperty("relaxedQueryChars", specialCharacters);
        });
    }
}
